///////////////////////////////////////////////////////////////////////////////
//
// lighthouse3D - 3D Software Library
//
// File: CMathe3D.h
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003-2013 Marcus Reinhardt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
//
// You can find a copy of the GNU General Public License (gpl.txt) in the
// directory of the library.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef _CMathe3D_H_
#define _CMathe3D_H_

#include "math.h"

#include "CBasicClasses.h"

///////////////////////////////////////////////////////////////////////////////
// class CMathe3D : Basic mathematical routines required for the geometric
//                  operations              
///////////////////////////////////////////////////////////////////////////////

// some important macros
#define ABS(a) ( ((a)<0)?(-(a)):(a) )
#define SGN(x) ( (!(x))?(0):(((x)<0)?(-1):(1)) )
#define MIN(a,b) ( (a<b)?(a):(b) )
#define MAX(a,b) ( (a>b)?(a):(b) )
#define MaxPoint(a,b) ( (a->sy > b->sy) ? a : b )
#define MinPoint(a,b) ( (b->sy > a->sy) ? a : b )
#define MaxPoint3(a,b,c) MaxPoint( MaxPoint(a,b), MaxPoint(b,c) )
#define MidPoint3(a,b,c) MaxPoint( MinPoint(a,b), MinPoint(a,c) )
#define MinPoint3(a,b,c) MinPoint( MinPoint(a,b), MinPoint(b,c) )

#ifndef M_PI
	#define M_PI 3.14159265358979323846
#endif

//! Struct to store a 4x4 matrix

struct TMatrix4x4 {
  public:
    float d[4][4];
};

//! Struct to store a 3 dimensional vector

struct TVector3D {
  public:
    float d[3];
};

//! Basic mathematical routines required for 3D-operations

class CMathe3D {

  public:

    CMathe3D();
    ~CMathe3D();

    int round(float x);
    float powerof(float x, int y);

	float sqr(float x);
	float fastinvsqrt(float x);
	float fastinv(float x);
	float vectorLength(TVector3D v);
    float dotProduct(TVector3D v1, TVector3D v2);

    TVector3D rotateVector(TVector3D v, int ax, int ay, int az);
    TVector3D normalizeVector(TVector3D v);
    TVector3D multSkVector(float sk , TVector3D v);
    TVector3D addVectors(TVector3D v1, TVector3D v2);
    TVector3D subVectors(TVector3D v1, TVector3D v2);
    TVector3D doV3D(float x, float y, float z);
    TVector3D crossProduct(TVector3D v1, TVector3D v2);
    TVector3D transform(TVector3D v, TMatrix4x4 m);

    TMatrix4x4 matrixMul(TMatrix4x4 m1, TMatrix4x4 m2);
    TMatrix4x4 genRotMatrix(int m, int theta);
    TMatrix4x4 genRotMatrixComplex(TMatrix4x4 A, int m, int theta);
    TMatrix4x4 genSkalMatrix(float sx, float sy, float sz);
    TMatrix4x4 genTranMatrix(float tx, float ty, float tz);
    TMatrix4x4 genZeroMatrix();

    bool projection(TMeshVertex *v, float pjDist, int scX, int scY);
    bool projectionCamera(TMeshVertex *v, float pjDist, int scX, int scY);
    bool rotation(TMeshVertex *v,  int ax, int ay, int az);
    bool skalation(TMeshVertex *v,  float sx, float sy, float sz);
    bool translation(TMeshVertex *v,  float tx, float ty, float tz);
    bool translationCamera(TMeshVertex *v,  float tx, float ty, float tz);

  private:

    float sinC[360];
    float cosC[360];
};

#endif

